﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CTEM.Controllers.BUS;
using CTEM.Controllers.Global;
using CTEM.Models;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.DXErrorProvider;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;

namespace CTEM.ModuleForms.ManageLedger
{
    public partial class LedgerManagement : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private readonly LedgerBUS _ledgerBus = new LedgerBUS();
        private List<LedgerDTO> _listLedger = new List<LedgerDTO>();
        private List<SendTypeDTO> _listSendType = new List<SendTypeDTO>();
        private readonly List<LedgerDTO> _listLedgerHistory = new List<LedgerDTO>();
        private bool _isNew;
        private bool _isUpdate;
        private bool _isEdit;

        public LedgerManagement()
        {
            InitializeComponent();
            gridView1.BestFitColumns();
            _isNew = false;
            _isUpdate = false;
            LoadLedger();
        }

        private void LoadLedger()
        {
            _listLedger = _ledgerBus.LoadAllLedger();
            _listSendType = _ledgerBus.LoadSendType();
            _listSendType.Insert(0, new SendTypeDTO(0, Constants.EMPTY_TEXT));
            ledgerDTOBindingSource.DataSource = _listLedger;
            sendTypeDTOBindingSource.DataSource = _listSendType;
        }

        private static LedgerDTO ConvertValueForLedger (LedgerDTO ledger)
        {
            if (String.IsNullOrEmpty(ledger.FromAcc))
                ledger.FromAcc = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.FromBank))
                ledger.FromBank = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.FromNum))
                ledger.FromNum = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.ToAcc))
                ledger.ToAcc = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.ToBank))
                ledger.ToBank = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.ToNum))
                ledger.ToNum = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.Sender))
                ledger.Sender = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.Taker))
                ledger.Taker = Constants.EMPTY_TEXT;

            if (String.IsNullOrEmpty(ledger.Person))
            {
                ledger.Person = Constants.EMPTY_TEXT;
            }
            else
            {
                ledger.Person = Global.TitleCase(ledger.Person.TrimEnd());
            }
            if (String.IsNullOrEmpty(ledger.Reason))
            {
                ledger.Reason = Constants.EMPTY_TEXT;
            }
            else
            {
                ledger.Reason = Global.TitleCase(ledger.Reason.TrimEnd());
            }

          
            return ledger;
        }

        private void repositoryItemComboBox2_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {

            var button = e.Button;
            var index = gridView1.FocusedRowHandle;
            var ledger = gridView1.GetRow(index) as LedgerDTO;

            if (button.Index == 0) return;
            if (ledger != null)
                if (ledger.Method != null)
                {
                    if (button.Index == 1 && ledger.Method.ToUpper().CompareTo("CHUYỂN KHOẢNG") == 0)
                    {
                        var detailsForm = new Details(ledger.LedgerID);
                        detailsForm.ShowDialog();
                    }

                }
                else MessageBox.Show("Hãy cập nhật \"Chi Tiết\" sau khi đã tạo phiếu", "Hướng Dẫn");
                    
        }

        private bool ValidateLedger(LedgerDTO ledger, out string output, out int i)
        {
            i = 0;
            long number;
            if (String.IsNullOrEmpty(ledger.Name))
            {
                output = "Xin hãy nhập Mã Phiếu";
                i = 0;
                return false;
            }

            foreach (var ledgerDto in _listLedger)
            {
                if (!ledgerDto.Name.ToUpper().Trim().Equals(ledger.Name.ToUpper().Trim()) ||
                    ledgerDto.LedgerID.CompareTo(ledger.LedgerID) == 0) continue;
                i = 1;
                output =
                    string.Format("Mã Phiếu \"{0}\" mà bạn vừa nhập đã tồn tại.\n Vui lòng nhập lại Mã Phiếu khác.", ledger.Name);
                return false;
            }

            if (String.IsNullOrEmpty(ledger.Type))
            {
                output = "Xin hãy chọn Loại";
                i = 1;
                return false;
            }
            if (ledger.Type == "Chi" && ledger.Kind == 0)
            {
                output = "Xin hãy chọn Loại Chi";
                i = 2;
                return false;
            }
            if (ledger.Type == "Thu" && ledger.Kind != 0)
            {
                output = "Không cần nhập \"Loại Chi\" đối với phiếu thu";
                i = 2;
                return false;
            }
            if (String.IsNullOrEmpty(ledger.NumberFormated))
            {
                output = "Xin hãy nhập Số Tiền";
                i = 3;
                return false;
            }
            if (!long.TryParse(Global.RemoveSpace(ledger.NumberFormated), out number))
            {
                output = "Bạn đã nhập sai Số tiền";
                i = 3;
                return false;
            }
            if (String.IsNullOrEmpty(ledger.Method))
            {
                output = "Xin hãy chọn Hình Thức";
                i = 6;
                return false;
            }
            output = "";
            return true;

        }
        private bool ValidateLedgerUpdate(LedgerDTO ledger, out string output, out int i)
        {
            i = 0;
            long number;
            if (String.IsNullOrEmpty(ledger.Name))
            {
                output = "Xin hãy nhập Mã Phiếu";
                i = 0;
                return false;
            }

            if (String.IsNullOrEmpty(ledger.Type))
            {
                output = "Xin hãy chọn Loại";
                i = 1;
                return false;
            }
            if (ledger.Type == "Chi" && ledger.Kind == 0)
            {
                output = "Xin hãy chọn Loại Chi";
                i = 2;
                return false;
            }
            if (ledger.Type == "Thu" && ledger.Kind != 0)
            {
                output = "Không cần nhập \"Loại Chi\" đối với phiếu thu";
                i = 2;
                return false;
            }
            if (String.IsNullOrEmpty(ledger.NumberFormated))
            {
                output = "Xin hãy nhập Số Tiền";
                i = 3;
                return false;
            }
            if (!long.TryParse(Global.RemoveSpace(ledger.NumberFormated), out number))
            {
                output = "Bạn đã nhập sai Số tiền";
                i = 3;
                return false;
            }
            if (String.IsNullOrEmpty(ledger.Method))
            {
                output = "Xin hãy chọn Hình Thức";
                i = 6;
                return false;
            }
            output = "";
            return true;
        }

        private void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            if (!_isNew)
            {
                var view = sender as ColumnView;
                var i = e.RowHandle;
                var ledger = gridView1.GetRow(i) as LedgerDTO;
                if (ledger != null)
                {
                    var oldLedger = _ledgerBus.GetLedgerByID(ledger.LedgerID);
                    string message;
                    int pos;
                    if (!oldLedger.Name.Equals(ledger.Name))
                    {
                        if (!ValidateLedger(ledger, out message, out pos))
                        {
                            DialogResult result = MessageBox.Show(message + "\nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                            view.SetColumnError(view.Columns[pos], message, ErrorType.Warning);
                            if (result == DialogResult.No)
                            {
                                _isUpdate = false;
                                view.ClearColumnErrors();
                                LoadLedger();
                                return;
                            }
                            else
                            {
                                _isUpdate = true;
                                gridView1.FocusedRowHandle = i;
                                gridView1.FocusedColumn = e.Column;
                                return;
                            }
                        }
                    }
                    else
                    {
                        if (!ValidateLedgerUpdate(ledger, out message, out pos))
                        {
                            DialogResult result = MessageBox.Show(message + "\nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                            view.SetColumnError(view.Columns[pos], message, ErrorType.Warning);
                            if (result == DialogResult.No)
                            {
                                _isUpdate = false;
                                view.ClearColumnErrors();
                                LoadLedger();
                                return;
                            }
                            else
                            {
                                _isUpdate = true;
                                gridView1.FocusedRowHandle = i;
                                gridView1.FocusedColumn = e.Column;
                                return;
                            }
                        }
                    }
                    ledger = ConvertValueForLedger(ledger);
                    if (!_ledgerBus.updateLedger(ledger))
                    {
                        MessageBox.Show("Không thể cập nhật thông tin", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        _isUpdate = false;
                        LoadLedger();
                    }
                    else
                    {
                        _isUpdate = false;
                        LoadLedger();
                        if (oldLedger != null)
                        {
                            oldLedger.Status = 2;
                            _listLedgerHistory.Add(oldLedger);
                        }
                        alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã chỉnh sửa phiếu {0} sô {1} Thành Công!", ledger.Type, ledger.Name));
                    }
                }
            }
        }

        private void gridView1_ValidateRow(object sender, ValidateRowEventArgs e)
        {
            if (_isNew)
            {
                var view = sender as ColumnView;
                var ledger = e.Row as LedgerDTO;
                string message;
                int pos;

                    if (!ValidateLedger(ledger, out message, out pos))
                    {
                        e.Valid = false;
                        if (view != null)
                        {
                            view.ClearColumnErrors();
                            view.SetColumnError(view.Columns[pos], message, ErrorType.Warning);
                        }
                        DialogResult result = MessageBox.Show(message + "\nBạn có muốn nhập lại thông tin", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                        if (result == DialogResult.No)
                        {
                            _isNew = false;
                            e.Valid = true;
                            LoadLedger();
                        }
                    }
                    else
                    {
                        ledger = ConvertValueForLedger(ledger);
                        long success = _ledgerBus.CreateLedger((ledger));
                        if (success == 0)
                        {
                            e.Valid = false;
                            LoadLedger();
                        }
                        else
                        {
                            if (ledger != null)
                            {
                                ledger.LedgerID = success;
                                ledger.Status = 1;
                                _listLedgerHistory.Add(ledger);
                                alertControlMain.Show(this, Constants.CONFIRM, String.Format("Bạn Đã tạo mới phiếu {0} sô {1} Thành Công!",ledger.Type,ledger.Name));
                            }
                            _isNew = false;
                            LoadLedger();
                        }
                    }
            }
        }

        private void gridView1_FocusedRowChanged(object sender, FocusedRowChangedEventArgs e)
        {
          if (e.FocusedRowHandle == DevExpress.XtraGrid.GridControl.NewItemRowHandle)
            {

                gridView1.OptionsBehavior.ReadOnly = false;

            }
          else
            {
                gridView1.OptionsBehavior.ReadOnly = !_isEdit;
            }
        
        }

        private void gridView1_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            _isNew = true;
            gridView1.SetRowCellValue(e.RowHandle, "Date", DateTime.Today);
            gridView1.SetRowCellValue(e.RowHandle, "SendDate", DateTime.Today);
        }

        private void gridView1_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
        {
            e.ExceptionMode = ExceptionMode.NoAction;
        }

        private void btnSendType_ItemClick(object sender, ItemClickEventArgs e)
        {
            var spendTypeManagement = new SpendTypeManagement();
            spendTypeManagement.ShowDialog();
            LoadLedger();
        }

        private void btnDelete_ItemClick(object sender, ItemClickEventArgs e)
        {
            int rowIndex = gridView1.FocusedRowHandle;
            var ledger = gridView1.GetRow(rowIndex) as LedgerDTO;
            if (ledger != null)
                if (MessageBox.Show(string.Format("Bạn có chắc chắn muốn xóa Phiếu \"{0}\" không?", ledger.Name), "Cảnh báo", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    bool success = _ledgerBus.delete(ledger.LedgerID);
                    if (success)
                    {
                        LoadLedger();
                        ledger.Status = 3;
                        _listLedgerHistory.Add(ledger);
                    }
                    else
                        MessageBox.Show("Không thể xóa phương tiện này.", "Cảnh báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
        }

        private void tbnUndo_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_listLedgerHistory.Count <= 0) return;
            var undoItem = _listLedgerHistory[_listLedgerHistory.Count - 1];
            switch (undoItem.Status)
            {
                case 1:
                    foreach (var ledger in _listLedger)
                        if (undoItem.LedgerID == ledger.LedgerID)
                        {
                            _ledgerBus.delete(ledger.LedgerID);
                            _listLedgerHistory.RemoveAt(_listLedgerHistory.Count - 1);
                            LoadLedger();
                            break;
                        }
                    break;
                case 2:
                    foreach (var ledger in _listLedger)
                        if (undoItem.LedgerID == ledger.LedgerID)
                        {
                            _ledgerBus.updateLedger(undoItem);
                            _listLedgerHistory.RemoveAt(_listLedgerHistory.Count - 1);
                            LoadLedger();
                            break;
                        }
                    break;
                case 3:
                    _ledgerBus.CreateLedger(undoItem);
                    _listLedgerHistory.RemoveAt(_listLedgerHistory.Count - 1);
                    LoadLedger();
                    break;
                default:
                    break;
            }
        }

        private void bntEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            gridView1.OptionsBehavior.ReadOnly = false;
        }

        private void LedgerManagement_Load(object sender, EventArgs e)
        {
            LoadLedger();
            _isEdit = false;
        }

    }
}